//
// CXSparseAPI.cpp
//
// Code generation for function 'CXSparseAPI'
//

// Include files
#include "CXSparseAPI.h"
#include "detrendIBI_priors_data.h"
#include "detrendIBI_priors_internal_types.h"
#include "eml_int_forloop_overflow_check.h"
#include "indexShapeCheck.h"
#include "rt_nonfinite.h"
#include "sparse1.h"
#include "warning.h"
#include "coder_array.h"
#include "CXSparse/CXSparseSupport/cs.h"
#include "CXSparse/CXSparseSupport/makeCXSparseMatrix.h"
#include "CXSparse/CXSparseSupport/solve_from_lu.h"
#include "CXSparse/CXSparseSupport/solve_from_qr.h"
#include <cstddef>
#include <cstring>

// Variable Definitions
static emlrtRSInfo
    cg_emlrtRSI{
        289,                      // lineNo
        "CXSparseAPI/iteratedLU", // fcnName
        "D:\\Program "
        "Files\\MATLAB\\R2022a\\toolbox\\eml\\eml\\+coder\\+"
        "internal\\CXSparseAPI.m" // pathName
    };

static emlrtRSInfo
    dg_emlrtRSI{
        309,                      // lineNo
        "CXSparseAPI/iteratedLU", // fcnName
        "D:\\Program "
        "Files\\MATLAB\\R2022a\\toolbox\\eml\\eml\\+coder\\+"
        "internal\\CXSparseAPI.m" // pathName
    };

static emlrtRSInfo
    eg_emlrtRSI{
        312,                      // lineNo
        "CXSparseAPI/iteratedLU", // fcnName
        "D:\\Program "
        "Files\\MATLAB\\R2022a\\toolbox\\eml\\eml\\+coder\\+"
        "internal\\CXSparseAPI.m" // pathName
    };

static emlrtRSInfo
    fg_emlrtRSI{
        324,                      // lineNo
        "CXSparseAPI/iteratedLU", // fcnName
        "D:\\Program "
        "Files\\MATLAB\\R2022a\\toolbox\\eml\\eml\\+coder\\+"
        "internal\\CXSparseAPI.m" // pathName
    };

static emlrtRSInfo
    gg_emlrtRSI{
        328,                      // lineNo
        "CXSparseAPI/iteratedLU", // fcnName
        "D:\\Program "
        "Files\\MATLAB\\R2022a\\toolbox\\eml\\eml\\+coder\\+"
        "internal\\CXSparseAPI.m" // pathName
    };

static emlrtRSInfo
    hg_emlrtRSI{
        331,                      // lineNo
        "CXSparseAPI/iteratedLU", // fcnName
        "D:\\Program "
        "Files\\MATLAB\\R2022a\\toolbox\\eml\\eml\\+coder\\+"
        "internal\\CXSparseAPI.m" // pathName
    };

static emlrtRSInfo
    ig_emlrtRSI{
        336,                      // lineNo
        "CXSparseAPI/iteratedLU", // fcnName
        "D:\\Program "
        "Files\\MATLAB\\R2022a\\toolbox\\eml\\eml\\+coder\\+"
        "internal\\CXSparseAPI.m" // pathName
    };

// Function Definitions
namespace coder {
namespace internal {
void CXSparseAPI::iteratedLU(const emlrtStack *sp, const sparse *A,
                             const sparse *b, sparse *out)
{
  cs_di *cxA;
  cs_din *N;
  cs_dis *S;
  b_sparse s;
  array<real_T, 2U> tmp;
  array<real_T, 1U> b_outBuff;
  array<real_T, 1U> outBuff;
  d_struct_T rhsIter;
  emlrtStack b_st;
  emlrtStack c_st;
  emlrtStack d_st;
  emlrtStack e_st;
  emlrtStack f_st;
  emlrtStack st;
  int32_T iv[2];
  int32_T k;
  int32_T nzColAlloc;
  int32_T nzRhs;
  st.prev = sp;
  st.tls = sp->tls;
  b_st.prev = &st;
  b_st.tls = st.tls;
  c_st.prev = &b_st;
  c_st.tls = b_st.tls;
  d_st.prev = &c_st;
  d_st.tls = c_st.tls;
  e_st.prev = &d_st;
  e_st.tls = d_st.tls;
  f_st.prev = &e_st;
  f_st.tls = e_st.tls;
  emlrtHeapReferenceStackEnterFcnR2012b((emlrtCTX)sp);
  nzColAlloc = A->n;
  st.site = &cg_emlrtRSI;
  if (A->m < A->n) {
    b_st.site = &jg_emlrtRSI;
    c_st.site = &jg_emlrtRSI;
    A->ctranspose(&c_st, out);
    cxA = makeCXSparseMatrix(out->colidx[out->colidx.size(0) - 1] - 1, out->n,
                             out->m, &(out->colidx.data())[0],
                             &(out->rowidx.data())[0], &(out->d.data())[0]);
  } else {
    b_st.site = &kg_emlrtRSI;
    cxA = makeCXSparseMatrix(
        A->colidx[A->colidx.size(0) - 1] - 1, A->n, A->m,
        &(((::coder::array<int32_T, 1U> *)&A->colidx)->data())[0],
        &(((::coder::array<int32_T, 1U> *)&A->rowidx)->data())[0],
        &(((::coder::array<real_T, 1U> *)&A->d)->data())[0]);
  }
  S = cs_di_sqr(2, cxA, 0);
  N = cs_di_lu(cxA, S, 1);
  cs_di_spfree(cxA);
  if (N == nullptr) {
    cs_di *b_cxA;
    cs_din *b_N;
    cs_dis *b_S;
    real_T tol;
    int32_T extraSpace;
    int32_T nelem;
    st.site = &dg_emlrtRSI;
    warning(&st);
    cs_di_sfree(S);
    cs_di_nfree(N);
    st.site = &eg_emlrtRSI;
    b_st.site = &lg_emlrtRSI;
    if (A->m < A->n) {
      c_st.site = &jg_emlrtRSI;
      d_st.site = &jg_emlrtRSI;
      A->ctranspose(&d_st, out);
      b_cxA = makeCXSparseMatrix(out->colidx[out->colidx.size(0) - 1] - 1,
                                 out->n, out->m, &(out->colidx.data())[0],
                                 &(out->rowidx.data())[0], &(out->d.data())[0]);
    } else {
      c_st.site = &kg_emlrtRSI;
      b_cxA = makeCXSparseMatrix(
          A->colidx[A->colidx.size(0) - 1] - 1, A->n, A->m,
          &(((::coder::array<int32_T, 1U> *)&A->colidx)->data())[0],
          &(((::coder::array<int32_T, 1U> *)&A->rowidx)->data())[0],
          &(((::coder::array<real_T, 1U> *)&A->d)->data())[0]);
    }
    b_S = cs_di_sqr(2, b_cxA, 1);
    b_N = cs_di_qr(b_cxA, b_S);
    cs_di_spfree(b_cxA);
    qr_rank_di(b_N, &tol);
    b_st.site = &mg_emlrtRSI;
    sparse::spallocLike(&b_st, A->n, static_cast<real_T>(b->n), out);
    nelem = b->m;
    if (b->m < A->n) {
      outBuff.set_size(&ed_emlrtRTEI, &st, A->n);
    } else {
      outBuff.set_size(&dd_emlrtRTEI, &st, b->m);
    }
    extraSpace = b->n;
    if (extraSpace - 1 >= 0) {
      if (nelem < 1) {
        nzRhs = 0;
      } else {
        nzRhs = nelem;
      }
      if (A->n < 1) {
        k = 0;
      } else {
        k = nzColAlloc;
      }
      iv[0] = 1;
      iv[1] = k;
    }
    for (int32_T i{0}; i < extraSpace; i++) {
      b_st.site = &ng_emlrtRSI;
      b->parenReference(&b_st, static_cast<real_T>(i) + 1.0, &s);
      b_st.site = &ng_emlrtRSI;
      s.full(&b_st, tmp);
      for (nelem = 0; nelem < nzRhs; nelem++) {
        outBuff[nelem] = tmp[nelem];
      }
      solve_from_qr_di(b_N, b_S, (double *)&(outBuff.data())[0], b->m,
                       nzColAlloc);
      b_st.site = &og_emlrtRSI;
      indexShapeCheck(&b_st, outBuff.size(0), iv);
      b_outBuff.set_size(&fd_emlrtRTEI, &st, k);
      for (nelem = 0; nelem < k; nelem++) {
        b_outBuff[nelem] = outBuff[nelem];
      }
      b_st.site = &og_emlrtRSI;
      out->parenAssign(&b_st, b_outBuff, static_cast<real_T>(i) + 1.0);
    }
    cs_di_sfree(b_S);
    cs_di_nfree(b_N);
  } else {
    int32_T b_b;
    st.site = &fg_emlrtRSI;
    sparse::spallocLike(&st, A->n, static_cast<real_T>(b->n), out);
    b_b = b->n;
    st.site = &gg_emlrtRSI;
    if (b->n > 2147483646) {
      b_st.site = &y_emlrtRSI;
      check_forloop_overflow_error(&b_st);
    }
    for (int32_T i{0}; i < b_b; i++) {
      int32_T extraSpace;
      st.site = &hg_emlrtRSI;
      b_st.site = &pg_emlrtRSI;
      c_st.site = &qg_emlrtRSI;
      d_st.site = &rg_emlrtRSI;
      if (i + 1 > b->n) {
        emlrtErrorWithMessageIdR2018a(
            &d_st, &gb_emlrtRTEI, "Coder:builtins:IndexOutOfBounds",
            "Coder:builtins:IndexOutOfBounds", 6, 12, i + 1, 12, 1, 12, b->n);
      }
      extraSpace = b->colidx[i];
      nzColAlloc = b->colidx[i + 1] - extraSpace;
      if ((nzColAlloc > b->m) && (b->m != 0)) {
        emlrtErrorWithMessageIdR2018a(&c_st, &fb_emlrtRTEI,
                                      "Coder:builtins:AssertionFailed",
                                      "Coder:builtins:AssertionFailed", 0);
      }
      d_st.site = &sg_emlrtRSI;
      sparse::spallocLike(&d_st, b->m, nzColAlloc, &s);
      if (nzColAlloc != 0) {
        d_st.site = &tg_emlrtRSI;
        if (nzColAlloc > 2147483646) {
          e_st.site = &y_emlrtRSI;
          check_forloop_overflow_error(&e_st);
        }
        for (k = 0; k < nzColAlloc; k++) {
          s.d[k] = 1.0;
          s.rowidx[k] = b->rowidx[(extraSpace + k) - 1];
        }
        s.colidx[1] = s.colidx[0] + nzColAlloc;
      }
      st.site = &hg_emlrtRSI;
      s.full(&st, tmp);
      solve_from_lu_di(N, S, (double *)&tmp[0], b->m);
      st.site = &ig_emlrtRSI;
      b_st.site = &vg_emlrtRSI;
      if (out->m != tmp.size(0)) {
        emlrtErrorWithMessageIdR2018a(&b_st, &eb_emlrtRTEI,
                                      "MATLAB:subsassigndimmismatch",
                                      "MATLAB:subsassigndimmismatch", 0);
      }
      c_st.site = &xg_emlrtRSI;
      d_st.site = &yg_emlrtRSI;
      if (i + 1 > out->n) {
        emlrtErrorWithMessageIdR2018a(
            &d_st, &gb_emlrtRTEI, "Coder:builtins:IndexOutOfBounds",
            "Coder:builtins:IndexOutOfBounds", 6, 12, i + 1, 12, 1, 12, out->n);
      }
      extraSpace = out->m;
      nzColAlloc = out->colidx[i + 1] - out->colidx[i];
      d_st.site = &ah_emlrtRSI;
      rhsIter.idx = 1;
      nzRhs = 0;
      e_st.site = &ih_emlrtRSI;
      if (out->m > 2147483646) {
        f_st.site = &y_emlrtRSI;
        check_forloop_overflow_error(&f_st);
      }
      for (k = 0; k < extraSpace; k++) {
        real_T tol;
        tol = tmp[rhsIter.idx - 1];
        rhsIter.idx++;
        if (!(tol == 0.0)) {
          nzRhs++;
        }
      }
      if (nzColAlloc < nzRhs) {
        nzRhs -= nzColAlloc;
        extraSpace = (out->maxnz - out->colidx[out->colidx.size(0) - 1]) + 1;
        if (extraSpace < nzRhs) {
          d_st.site = &bh_emlrtRSI;
          sparse::b_realloc(&d_st, out, (out->maxnz + nzRhs) - extraSpace,
                            out->colidx[i] - 1, out->colidx[i + 1],
                            out->colidx[out->colidx.size(0) - 1] - 1, nzRhs);
        } else {
          int32_T nelem;
          d_st.site = &ch_emlrtRSI;
          nzColAlloc = (out->colidx[i + 1] + nzRhs) - 1;
          nelem = out->colidx[out->colidx.size(0) - 1] - out->colidx[i + 1];
          if (nelem > 0) {
            e_st.site = &mh_emlrtRSI;
            std::memmove((void *)&out->rowidx[nzColAlloc],
                         (void *)&out->rowidx[out->colidx[i + 1] - 1],
                         (uint32_T)((size_t)nelem * sizeof(int32_T)));
            e_st.site = &nh_emlrtRSI;
            std::memmove((void *)&out->d[nzColAlloc],
                         (void *)&out->d[out->colidx[i + 1] - 1],
                         (uint32_T)((size_t)nelem * sizeof(real_T)));
          }
        }
        rhsIter.idx = 1;
        rhsIter.col = 1;
        rhsIter.row = 1;
        d_st.site = &dh_emlrtRSI;
        sparse::copyNonzeroValues(&d_st, out, &rhsIter, out->colidx[i], tmp);
        d_st.site = &eh_emlrtRSI;
        sparse::incrColIdx(&d_st, out, i + 1, nzRhs);
      } else {
        rhsIter.idx = 1;
        rhsIter.col = 1;
        rhsIter.row = 1;
        d_st.site = &fh_emlrtRSI;
        k = sparse::copyNonzeroValues(&d_st, out, &rhsIter, out->colidx[i],
                                      tmp) -
            1;
        extraSpace = nzColAlloc - nzRhs;
        if (extraSpace > 0) {
          int32_T nelem;
          d_st.site = &gh_emlrtRSI;
          nelem = out->colidx[out->colidx.size(0) - 1] - out->colidx[i + 1];
          if (nelem > 0) {
            e_st.site = &mh_emlrtRSI;
            std::memmove((void *)&out->rowidx[k],
                         (void *)&out->rowidx[out->colidx[i + 1] - 1],
                         (uint32_T)((size_t)nelem * sizeof(int32_T)));
            e_st.site = &nh_emlrtRSI;
            std::memmove((void *)&out->d[k],
                         (void *)&out->d[out->colidx[i + 1] - 1],
                         (uint32_T)((size_t)nelem * sizeof(real_T)));
          }
          d_st.site = &hh_emlrtRSI;
          sparse::decrColIdx(&d_st, out, i + 1, extraSpace);
        }
      }
    }
    cs_di_sfree(S);
    cs_di_nfree(N);
  }
  emlrtHeapReferenceStackLeaveFcnR2012b((emlrtCTX)sp);
}

} // namespace internal
} // namespace coder

// End of code generation (CXSparseAPI.cpp)
